using System.Linq;

namespace Core.Features
{
    using System;
    using Base;
    using Contracts.Enums;
    using Contracts.Interfaces;
    using Resources;

    
    public sealed class MediumMagneticWeaponHitDispersion<T> : FeatureBase<object>
    {
        public MediumMagneticWeaponHitDispersion(){}

        public MediumMagneticWeaponHitDispersion(T value) 
            : base(value){ }
        /// <summary>
        /// Obtains the feature name
        /// </summary>
        public override string Name
        {
            get { return "hit dispersion"; }
        }
        /// <summary>
        /// Obtains the feature group
        /// </summary>
        public override FeatureGroupsEnum FeatureGroup{ get { return FeatureGroupsEnum.Specific; } }
        /// <summary>
        /// Obtains the feature type
        /// </summary>
        public override FeaturesEnum FeatureType { get { return FeaturesEnum.MediumMagneticWeaponHitDispersion; } }
        /// <summary>
        /// Obtains or defines the feature unit
        /// </summary>
        public override string Unit { get { return Traduction.label_unit_degree; } }

        public override void SetModifiedValue(IAgent agent, IRobot robot)
        {
            if (agent == null || robot == null) return;
            // Bonus from PrecisionFiring extension
            double temp = (double)Value * (1 + agent.Extensions
                                                    .Where(e => e.GetType() == typeof(Extensions.PrecisionFiring))
                                                    .SumModifiersValues(FeatureTypesEnum.Module, this.FeatureType));

            // Bonus from robot
            temp *= 1 + robot.Modifiers.SumModifiersValues(agent.Extensions, FeatureTypesEnum.Module, this.FeatureType);

            // Bonus from Weapon stabilizers
            temp = robot.Modules
                .Where(m => m.Modifiers != null && m.Modifiers.Any())
                .Select(module => module.Modifiers.Where(m => m.ModifiedFeatureType == FeatureTypesEnum.Module && m.Feature == this.FeatureType))
                .Where(mods => mods.Any())
                .Aggregate(temp, (current1, mods) => mods.Aggregate(current1, (current, modifier) => current * (1 + modifier.Value)));

            ModifiedValue = IsRounded
                ? Math.Round(temp, 0, MidpointRounding.AwayFromZero)
                : Math.Round(temp, 2);
        }
    }
}